package com.xltq.controller;

import com.xltq.utils.Constants;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Objects;

@WebServlet(name = "BaseServlet")
public class BaseServlet extends HttpServlet {
    //只要提供一个Service方法重写就可以解决 doGet和doPost之间的调用问题
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         //1.获取请求方法参数表示符 --> method
        //外界所有JSP页面发送方法的时候一定都是method作为方法拼接的key值
        String methodStr = req.getParameter(Constants.TAG);
        //2.如果method没有获取值!我们就跳转到主页
        if(methodStr == null && methodStr.equals("")){
            methodStr = Constants.INDEX;
        }
        //3.提供反射获取子类servlet中需要调用的方法
        Class clazz = this.getClass();
        //通过反射获取当前子类Servlet中的方对象
        //调用通过反射获取方法对象的方法是 getMethod并不是暴力反射,所以子类中提供方法必须是public修改
        try {
            Method method = clazz.getMethod(methodStr, HttpServletRequest.class, HttpServletResponse.class);
            //通过获取到method对象执行子类中提供的对应方法并接受子类的响应返回
            Object result = method.invoke(this, req, resp);
            //因为要统一处理,所以需要进行返回
            //4.判断接受到的这个返回值
            if(Objects.nonNull(result)){
                //转发 ,重定向 ,返回字符串结果集
                String str = (String) result;
                /**
                 * 你在提供同意模块处理的Servlet中 提供方法
                 * 第一必须使用public
                 * 第二个方法要么有返回值即String
                 * return 使用Constants中定义的字符串进行拼接
                 * 例如: 转发一个消息界面  --> return  Constants.FORWARD+"/message.jsp";
                 * 方法要么就没有返回即 void
                 */
                if(str.startsWith(Constants.FORWARD)){
                    //响应的就是请求转发
                    String path = str.substring(str.indexOf(Constants.FLAG) + 1);
                    //只需要转发路径即可
                    req.getRequestDispatcher(path).forward(req, resp);
                }else if(str.startsWith(Constants.REDIRECT)){
                    //响应的就是重定向
                    String path = str.substring(str.indexOf(Constants.FLAG) + 1);
                    resp.sendRedirect(path);
                }else{
                    //响应字符串到页面
                    resp.getWriter().println(str);
                }

            }
        } catch (Exception e) {
            //Controller , service 和 dao 有异常都是到此处
            e.printStackTrace();
            req.getSession().setAttribute("msg", "程序异常!请稍后再试!");
            resp.sendRedirect("/message.jsp");
        }
    }

    /**
     * 提供一个主页跳转方法,只要method标识符中没有值或是空串就进行主页条件
     * 将获取到methodStr经过判断之后赋值我 index 标识 ,所以提供一个index方法用于跳转
     * @param request
     * @param response
     * @return
     * @throws IOException
     * @throws ServletException
     */
    public String index(HttpServletRequest request,HttpServletResponse response) throws IOException,ServletException{
            return  Constants.FORWARD+"/index.jsp";
    }
}
